/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.bancofloripa.controller;

import br.com.bancofloripa.dao.*;
import br.com.bancofloripa.entity.*;
import br.com.bancofloripa.enums.ContaType;
import br.com.bancofloripa.exception.MensagemExceptionDAO;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;

/**
 *
 * @author fabianoc
 */
public class ContaController {
    
    private ContaDAO cd;
    private ContaOuroDAO cod;
    private ContaPoupancaDAO cpd;
    
    Cliente cl;
    Agencia ag;
    
    private ContaSimples csOrigem = null;
    private ContaOuro coOrigem = null;
    private ContaPoupanca cpOrigem = null;    
    private ContaSimples csDestino = null;
    private ContaOuro coDestino = null;
    private ContaPoupanca cpDestino = null;
    
    private double valor;
    private double saldoDestino;
    private double saldoOrigem;
    private int valorClick;
    private String tipo1;
    private String tipo2;
    
    public ContaController() {
    }
    
    
    
    /**
     * @param valor
     *            valor a ser sacado da conta
     */
    public synchronized double saque(JTextArea jt, Conta c, double valor) {
        System.out.println("conta "+c.getnConta());
        if (getTipo1().equalsIgnoreCase("simples")) {
            Conta cc = new ContaDAO().getById(c.getnConta());
            double saldoTotal = cc.getSaldo();
            if (saldoTotal >= valor){
                try {
                    cc.setSaldo(saldoTotal - valor) ;
                    setCd(new ContaDAO());
                    getCd().atualiza(cc);
                    this.preencheConsole(jt, "Saque efetuado com sucesso\n"+
                            "a conta "+cc.getnConta()+" do cliente "+cc.getCliente().getNome()+"\n"+
                            "ficou com saldo de "+cc.getSaldo()+"\n");
                } catch (MensagemExceptionDAO ex) {
                    Logger.getLogger(ContaController.class.getName()).log(Level.SEVERE, null, ex);
                }
            } 
        } else if (getTipo1().equalsIgnoreCase("ouro")) {
            ContaOuro co = new ContaOuroDAO().getById(c.getnConta());
            double saldoTotal = co.getLimite() + co.getSaldo();
            if (saldoTotal >= valor){
                try {
                    co.setSaldo(co.getSaldo() - valor) ;
                    setCod(new ContaOuroDAO());
                    getCod().atualiza(co);
                    this.preencheConsole(jt, "Saque efetuado com sucesso\n"+
                            "a conta "+co.getnConta()+" do cliente "+co.getCliente().getNome()+"\n"+
                            "ficou com saldo de "+co.getSaldo()+"\n");                    
                } catch (MensagemExceptionDAO ex) {
                    Logger.getLogger(ContaController.class.getName()).log(Level.SEVERE, null, ex);
                }
            } 
        } else if (getTipo1().equalsIgnoreCase("poup")) {
            ContaPoupanca cop = new ContaPoupancaDAO().getById(c.getnConta());
            if (cop.getSaldo() >= valor){
                System.out.println("IF "+c.getnConta());
                try {
                    cop.setSaldo(cop.getSaldo() - valor) ;
                    setCpd(new ContaPoupancaDAO());
                    getCpd().atualiza(cop);
                    this.preencheConsole(jt, "Saque efetuado com sucesso\n"+
                         "a conta "+cop.getnConta()+" do cliente "+cop.getCliente().getNome()+"\n"+
                         "ficou com saldo de "+cop.getSaldo()+"\n");
                } catch (MensagemExceptionDAO ex) {
                    Logger.getLogger(ContaController.class.getName()).log(Level.SEVERE, null, ex);
                }
            } 
        }
        return c.getSaldo();
    }

    /**
     * @param valor
     *            valor a ser depositado da conta
     */
    public synchronized double deposito(JTextArea jt, Conta c, double valor) {
        if (valor > 0) {
            System.out.println("conta "+c.getnConta());
            if (getTipo2().equalsIgnoreCase("simples")) {
                Conta cc = new ContaDAO().getById(c.getnConta());
                double saldoTotal = cc.getSaldo();
                    try {
                        cc.setSaldo(saldoTotal + valor) ;
                        setCd(new ContaDAO());
                        getCd().atualiza(cc);
                        this.preencheConsole(jt, "Deposito efetuado com sucesso\n"+
                                "a conta "+cc.getnConta()+" do cliente "+cc.getCliente().getNome()+"\n"+
                                "ficou com saldo de "+cc.getSaldo()+"\n");
                    } catch (MensagemExceptionDAO ex) {
                        //Logger.getLogger(ContaController.class.getName()).log(Level.SEVERE, null, ex);
                    }
            } else if (getTipo2().equalsIgnoreCase("ouro")) {
                ContaOuro co = new ContaOuroDAO().getById(c.getnConta());
                    try {
                        co.setSaldo(co.getSaldo() + valor) ;
                        setCod(new ContaOuroDAO());
                        getCod().atualiza(co);
                        this.preencheConsole(jt, "Deposito efetuado com sucesso\n"+
                                "a conta "+co.getnConta()+" do cliente "+co.getCliente().getNome()+"\n"+
                                "ficou com saldo de "+co.getSaldo()+"\n");                    
                    } catch (MensagemExceptionDAO ex) {
                        //Logger.getLogger(ContaController.class.getName()).log(Level.SEVERE, null, ex);
                    }
            } else if (getTipo2().equalsIgnoreCase("poup")) {
                ContaPoupanca cop = new ContaPoupancaDAO().getById(c.getnConta());
                    try {
                        cop.setSaldo(cop.getSaldo() + valor) ;
                        setCpd(new ContaPoupancaDAO());
                        getCpd().atualiza(cop);
                        this.preencheConsole(jt, "Deposito efetuado com sucesso\n"+
                            "a conta "+cop.getnConta()+" do cliente "+cop.getCliente().getNome()+"\n"+
                            "ficou com saldo de "+cop.getSaldo()+"\n");
                    } catch (MensagemExceptionDAO ex) {
                        //Logger.getLogger(ContaController.class.getName()).log(Level.SEVERE, null, ex);
                    }
            }
            return c.getSaldo();
        } else {
            JOptionPane.showMessageDialog(null, "Valor deve ser maior que zero.");
            return 0.00;
        }     
            
    }

    public void iniciaTransfer(JTextArea jt, JTextField campoValor, String tipo1, String tipo2) {
        this.setTipo1(tipo1);
        this.setTipo2(tipo2);
        try {
            String trans = "tranferencia executada com sucesso."+"\n";
                System.out.println(getCsDestino()+"transferencia1"+getCsOrigem());
                this.transfere(jt, getCsOrigem(), getCsDestino(), Double.parseDouble(campoValor.getText()));
                System.out.println("valor "+Double.parseDouble(campoValor.getText())+" / "+tipo1);
            this.preencheConsole(jt, trans);
            JOptionPane.showMessageDialog(null, trans);
        } catch (Exception ex) {
            Logger.getLogger(ContaController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }    

    public void transfere(JTextArea jt, Conta origem, Conta destino, double valor){
        try {
            this.saque(jt, origem, valor);
            Thread.sleep(500);
            this.deposito(jt, destino, valor);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
 
    }
    
    public void preencheConsole(JTextArea jt, String texto){
        jt.append(texto);
    }

    public void getClique(java.awt.event.MouseEvent evt, JTable jTable2, String tipo, String situacao) {
        ContaSimples cs = null;
        ContaOuro co = null;
        ContaPoupanca cp = null;           
        if ( evt.getClickCount() >= 1 ){
                this.setValorClick((int) (Integer) jTable2.getValueAt( jTable2.getSelectedRow() , 0));
               if (tipo.equalsIgnoreCase("simples")) {
                    cs = (ContaSimples) new ContaDAO().getById(getValorClick());
                    if(situacao.equalsIgnoreCase("origem")){
                        setCsOrigem(cs);
                    } else {
                        setCsDestino(cs);
                    }
                } 
               else if (tipo.equalsIgnoreCase("ouro")) {
                    co = new ContaOuroDAO().getById(getValorClick());
                    cs = new ContaSimples(co);
                    if(situacao.equalsIgnoreCase("origem")){
                        setCsOrigem(cs);
                    } else {
                        setCsDestino(cs);
                    }                  
                } else if (tipo.equalsIgnoreCase("poup")) {
                    cp = new ContaPoupancaDAO().getById(getValorClick());
                    cs = new ContaSimples(cp);
                    if(situacao.equalsIgnoreCase("origem")){
                        setCsOrigem(cs);
                    } else {
                        setCsDestino(cs);
                    }                    
                } 
                
        }  
    }
    
   public void atualizaTabela(List<Conta> lista, JTable tb ){

        DefaultTableModel model = (DefaultTableModel)tb.getModel();
        model.setRowCount( lista.size() );
        for ( int i = 0; i < lista.size(); i++ ){
            model.setValueAt( lista.get(i).getnConta() , i, 0);
            model.setValueAt( lista.get(i).getCliente().getNome() , i, 1);
         }
    }
   
   public List<Conta> montandoList(String tipo) {
       List<Conta> lista = new ArrayList<Conta>();
       List<ContaOuro> listaO = new ArrayList<ContaOuro>();
       List<ContaPoupanca> listaP = new ArrayList<ContaPoupanca>();
       if (tipo.equalsIgnoreCase("simples")) {
           lista = new ContaDAO().getAll();
       } else if (tipo.equalsIgnoreCase("ouro")) {
           listaO = new ContaOuroDAO().getAll();
           lista.addAll(listaO);
       } else if (tipo.equalsIgnoreCase("poup")) {
           listaP = new ContaPoupancaDAO().getAll();
           lista.addAll(listaP);
       }
    
       return lista;
       
   }   
   
   public void salvar(JTextField tfId, JTextField tfNumero,
           JComboBox jcbCli, JComboBox jcbAg, String tipo, 
           JTextField tfLimite, JTable jTable1){
         if (tfNumero.getText() != null && tfLimite.getText() != null) {  
            cl = (Cliente) jcbCli.getSelectedItem();
            ag = (Agencia) jcbAg.getSelectedItem();
            int nConta = 0;
            if (tfId != null) {
                nConta = Integer.parseInt(tfNumero.getText());
            }  else {
                return;
            }
            try {
                    if (tipo.equalsIgnoreCase("simples")) {
                        csOrigem = new ContaSimples(ag, nConta, 0.0, cl);
                        System.out.println(csOrigem.getnConta());
                        cd =new ContaDAO();
                        cd.insere(csOrigem);
                    } else if (tipo.equalsIgnoreCase("ouro")) {
                        double limite = Double.parseDouble(tfLimite.getText());
                        coOrigem = new ContaOuro(limite, ag, nConta, 0.0, cl);
                        cod = new ContaOuroDAO();
                        cod.insere(coOrigem);
                    } else if (tipo.equalsIgnoreCase("poup")) {
                        cpOrigem = new ContaPoupanca(ag, nConta, 0.0, cl);
                        cpd = new ContaPoupancaDAO();
                        cpd.insere(cpOrigem);
                    }              
                tfNumero.setText("");
                tfId.setText("");
                tfLimite.setText("");
                atualizaTabela(montandoList(tipo), jTable1);            
            } catch (Exception ex) {
    //            Logger.getLogger(AgenciaUi.class.getName()).log(Level.SEVERE, null, ex);
            } 
         }   
   }   
   
   public void comboClientes(JComboBox jcbCli){
       List<Cliente> lista = new ClienteDAO().getAll();
       ComboBoxModel model =  new DefaultComboBoxModel( lista.toArray() );
       jcbCli.setModel( model );
   }
   public void comboAgencia(JComboBox jcbAg){
       List<Agencia> lista = new AgenciaDAO().getAll();
       ComboBoxModel model =  new DefaultComboBoxModel( lista.toArray() );
       jcbAg.setModel( model );
   }   
   
   public void salvar(JTextField tfNumero, JComboBox jcbCli, 
           JComboBox jcbAg, JTextField tfLimite, String tipo, JTable jTable1){
       if (tfNumero.getText() != null) {  
            cl = (Cliente) jcbCli.getSelectedItem();
            ag = (Agencia) jcbAg.getSelectedItem();
            int conta = Integer.parseInt(tfNumero.getText());
            int limite = Integer.parseInt(tfLimite.getText());
            try {
                if (tipo.equalsIgnoreCase("simples")) {
                    csOrigem = new ContaSimples(ag, conta, 0, cl);
                    cd = new ContaDAO();
                    cd.insere(csOrigem);
                } else if (tipo.equalsIgnoreCase("ouro")) {
                    coOrigem = new ContaOuro(limite, ag, conta, 0, cl);
                    cod = new ContaOuroDAO();
                    cod.insere(coOrigem);                        
                } else if (tipo.equalsIgnoreCase("poup")) {
                    cpOrigem = new ContaPoupanca(ag, conta, 0, cl);
                    cpd = new ContaPoupancaDAO();
                    cpd.insere(cpOrigem);                        
                }              
                tfNumero.setText("");
                tfNumero.setText("0");
                atualizaTabela(montandoList(tipo), jTable1);            
            } catch (Exception ex) {
    //            Logger.getLogger(AgenciaUi.class.getName()).log(Level.SEVERE, null, ex);
            } 
         }   else {
             JOptionPane.showMessageDialog(null, "Deve informar o numero da conta.");
         }
   }   

    
    /**
     * @return the valor
     */
    public double getValor() {
        return valor;
    }

    /**
     * @param valor the valor to set
     */
    public void setValor(double valor) {
        if (valor > 0) {
            this.valor = valor;
        } else {
            JOptionPane.showMessageDialog(null, "O valor deve ser maior que zero.");
        }
    }

    /**
     * @return the saldoDestino
     */
    public double getSaldoDestino() {
        return saldoDestino;
    }

    /**
     * @param saldoDestino the saldoDestino to set
     */
    public void setSaldoDestino(double saldoDestino) {
        this.saldoDestino = saldoDestino;
    }

    /**
     * @return the saldoOrigem
     */
    public double getSaldoOrigem() {
        return saldoOrigem;
    }

    /**
     * @param saldoOrigem the saldoOrigem to set
     */
    public void setSaldoOrigem(double saldoOrigem) {
        this.saldoOrigem = saldoOrigem;
    }

    /**
     * @return the cd
     */
    public ContaDAO getCd() {
        return cd;
    }

    /**
     * @param cd the cd to set
     */
    public void setCd(ContaDAO cd) {
        this.cd = cd;
    }

    /**
     * @return the cod
     */
    public ContaOuroDAO getCod() {
        return cod;
    }

    /**
     * @param cod the cod to set
     */
    public void setCod(ContaOuroDAO cod) {
        this.cod = cod;
    }

    /**
     * @return the cpd
     */
    public ContaPoupancaDAO getCpd() {
        return cpd;
    }

    /**
     * @param cpd the cpd to set
     */
    public void setCpd(ContaPoupancaDAO cpd) {
        this.cpd = cpd;
    }

    /**
     * @return the csOrigem
     */
    public ContaSimples getCsOrigem() {
        return csOrigem;
    }

    /**
     * @param csOrigem the csOrigem to set
     */
    public void setCsOrigem(ContaSimples csOrigem) {
        this.csOrigem = csOrigem;
    }

    /**
     * @return the coOrigem
     */
    public ContaOuro getCoOrigem() {
        return coOrigem;
    }

    /**
     * @param coOrigem the coOrigem to set
     */
    public void setCoOrigem(ContaOuro coOrigem) {
        this.coOrigem = coOrigem;
    }

    /**
     * @return the cpOrigem
     */
    public ContaPoupanca getCpOrigem() {
        return cpOrigem;
    }

    /**
     * @param cpOrigem the cpOrigem to set
     */
    public void setCpOrigem(ContaPoupanca cpOrigem) {
        this.cpOrigem = cpOrigem;
    }

    /**
     * @return the csDestino
     */
    public ContaSimples getCsDestino() {
        return csDestino;
    }

    /**
     * @param csDestino the csDestino to set
     */
    public void setCsDestino(ContaSimples csDestino) {
        this.csDestino = csDestino;
    }

    /**
     * @return the coDestino
     */
    public ContaOuro getCoDestino() {
        return coDestino;
    }

    /**
     * @param coDestino the coDestino to set
     */
    public void setCoDestino(ContaOuro coDestino) {
        this.coDestino = coDestino;
    }

    /**
     * @return the cpDestino
     */
    public ContaPoupanca getCpDestino() {
        return cpDestino;
    }

    /**
     * @param cpDestino the cpDestino to set
     */
    public void setCpDestino(ContaPoupanca cpDestino) {
        this.cpDestino = cpDestino;
    }

    /**
     * @return the valorClick
     */
    public int getValorClick() {
        return valorClick;
    }

    /**
     * @param valorClick the valorClick to set
     */
    public void setValorClick(int valorClick) {
        this.valorClick = valorClick;
    }


    /**
     * @return the tipo1
     */
    public String getTipo1() {
        return tipo1;
    }

    /**
     * @param tipo1 the tipo1 to set
     */
    public void setTipo1(String tipo1) {
        this.tipo1 = tipo1;
    }

    /**
     * @return the tipo2
     */
    public String getTipo2() {
        return tipo2;
    }

    /**
     * @param tipo2 the tipo2 to set
     */
    public void setTipo2(String tipo2) {
        this.tipo2 = tipo2;
    }
    
}
